#include "WordWrapTextBox.h"
#include <string>
using namespace std;

WordWrapTextBox::WordWrapTextBox(int _x, int _y,int _colsize,int _rowsize, DrawingCanvas *_canvas)
{
	canvas = _canvas;
	colsize = _colsize;
	rowsize = _rowsize;
	pageX = _x; pageY = _y;
	
	topline = 0;
	charwidth = getCharWidth(canvas->getFont());
	charheight = 10;
	
	text = WrappedLineSet(colsize);
	vLines = ArrayList<Text *>();
	
	FilledRect(_x,_y,colsize * charwidth, rowsize * charheight,white,canvas);
	for(int i = 0; i < rowsize; i++)
	{
		vLines.add(new Text("",_x,_y + (i * charheight),black,canvas));
		vLines.get(i)->setFont(canvas->getFont());
		vLines.get(i)->setFontSize(0.5f);
		vLines.get(i)->setColor(RGB(0,0,0));
		vLines.get(i)->setBgColor(RGBA(0,0,0,0));
	}
	updateText();
}
WordWrapTextBox::WordWrapTextBox(string _initText, int _x, int _y, int _colsize, int _rowsize, DrawingCanvas *_canvas)
{
	canvas = _canvas;
	colsize = _colsize;
	rowsize = _rowsize;
	pageX = _x; pageY = _y;
	
	topline = 0;
	charwidth = getCharWidth(canvas->getFont());
	charheight = 10;
	
	text = WrappedLineSet(_initText,colsize);
	vLines = ArrayList<Text *>();
	
	FilledRect(_x,_y,colsize * charwidth, rowsize * charheight,white,canvas);
	for(int i = 0; i < rowsize; i++)
	{
		vLines.add(new Text("",_x,_y + (i * charheight),black,canvas));
		vLines.get(i)->setFont(canvas->getFont());
		vLines.get(i)->setFontSize(0.5f);
		vLines.get(i)->setColor(RGB(0,0,0));
		vLines.get(i)->setBgColor(RGBA(0,0,0,0));
	}
	updateText();
}

void WordWrapTextBox::updateText()
{
	for(int i = 0; i < vLines.size(); i++)
		vLines.get(i)->setText("");
	for(int i = 0; i < vLines.size() && i < text.getLineCount(); i++)
		vLines.get(i)->setText(text.getLine(i + topline));
}
void WordWrapTextBox::scrollUp()
{
	if(topline > 0)
		topline--;
	updateText();
}
void WordWrapTextBox::scrollDown()
{
	if(topline + vLines.size() < text.getLineCount())
		topline++;
	updateText();
}
void WordWrapTextBox::scrollBottom()
{
	if(vLines.size() > text.getLineCount())
		topline = 0;
	else
		topline = text.getLineCount() - vLines.size();
	updateText();
}
void WordWrapTextBox::scrollTop()
{
	topline = 0;
	updateText();
}
void WordWrapTextBox::setText(string _text)
{
	text = WrappedLineSet(_text,colsize);
	topline = 0;
	updateText();
}
string WordWrapTextBox::getText()
{
	return text.getText();
}

WrappedLineSet::WrappedLineSet(int _colsize)
{
	colsize = _colsize;
	wrappedLines = ArrayList<WrappedLine>();
	message = ArrayList<string>();
}
WrappedLineSet::WrappedLineSet(string initText, int _colsize)
{
	colsize = _colsize;
	wrappedLines = ArrayList<WrappedLine>();
	message = ArrayList<string>();
	
	vector<string> sarr = splitString(initText.c_str(),'\n');
	for(int i = 0; i < sarr.size(); i++)
	{
		message.add(sarr[i]);
		wrappedLines.add(WrappedLine(sarr[i],colsize));
	}
}

void WrappedLineSet::updateText()
{
	wrappedLines = ArrayList<WrappedLine>();
	for(int i = 0; i < message.size(); i++)
	{
		wrappedLines.add(WrappedLine(message.get(i),colsize));
	}
}
void WrappedLineSet::setText(string text)
{
	vector<string> sarr = splitString(text.c_str(),'\n');
	message = ArrayList<string>();
	for(int i = 0; i < sarr.size(); i++)
		message.add(sarr[i]);
	updateText();
}

int WrappedLineSet::getLineCount()
{
	int count = 0;
	for(int i = 0; i < wrappedLines.size(); i++)
		count += wrappedLines.get(i).getWrappedLineCount();
	return count;
}
string WrappedLineSet::getLine(int linenum)
{
	int count = 0;
	for(int i = 0; i < wrappedLines.size(); i++)
	{
		for(int z = 0; z < wrappedLines.get(i).getWrappedLineCount(); z++)
		{
			if(count == linenum)
				return wrappedLines.get(i).getLine(z);
			count++;
		}
	}
	return "";
}
string WrappedLineSet::getText()
{
	string str = "";
	for(int i = 0; i < wrappedLines.size(); i++)
	{
		str += wrappedLines[i].getText(); str += "\n";
	}
	return str;
}
WrappedLine::WrappedLine(int _colsize)
{
	colsize = _colsize;
	message = "";
	wrappedLines = ArrayList<string>();
}
WrappedLine::WrappedLine(string initText, int _colsize)
{
	colsize = _colsize;
	message = initText;
	wrappedLines = ArrayList<string>();
	
	vector<string> messagesplit = splitString(message.c_str(),'\n');
	message = "";
	for(int i = 0; i < messagesplit.size(); i++)
		message += messagesplit[i];
		
	vector<string> words = splitString(message.c_str(),' ');
	
	int spaceleft = colsize;
	string line = "";
	for(int i = 0; i < words.size(); i++)
	{
		if(words[i].length() > spaceleft)
		{
			if(line.length() < colsize)
				wrappedLines.add(line);
			else
			{
				string str = line;
				for(int z = 0; z < str.length(); z += colsize)
				{
					if(z + colsize >= str.length())
						wrappedLines.add(str.substr(z,str.length()));
					else
						wrappedLines.add(str.substr(z, colsize));
				}
			}
			line = words[i] + " ";
			spaceleft = colsize - line.length();
		}
		else
		{
			line += words[i] + " ";
			spaceleft = spaceleft - (words[i].length() + 1);
		}
	}
	if(line.length() < colsize)
		wrappedLines.add(line);
	else
	{
		string str = line;
		for(int z = 0; z < str.length(); z += colsize)
		{
			if(z + colsize >= str.length())
				wrappedLines.add(str.substr(z,str.length()));
			else
				wrappedLines.add(str.substr(z, colsize));
		}
	}
	
}

string WrappedLine::getLine(int linenum)
{
	return wrappedLines.get(linenum);
}
int WrappedLine::getWrappedLineCount()
{
	return wrappedLines.size();
}
string WrappedLine::getText()
{
	string str = "";
	for(int i = 0; i < wrappedLines.size(); i++)
		str += wrappedLines[i];
	return str;
}
